//! SeaORM 服务层
//! 提供通用的数据库操作方法

use sea_orm::{*, sea_query::Expr};
use std::sync::Arc;
use tracing::{error, info, instrument};

use crate::response::{AppError, AppResult};

/// SeaORM 服务抽象层
#[derive(Clone)]
pub struct SeaOrmService {
    db: Arc<DatabaseConnection>,
}

impl SeaOrmService {
    /// 创建新的 SeaORM 服务实例
    pub fn new(db: DatabaseConnection) -> Self {
        Self { db: Arc::new(db) }
    }

    /// 获取数据库连接
    pub fn db(&self) -> &DatabaseConnection {
        self.db.as_ref()
    }

    /// 检查数据库连接
    #[instrument(skip(self))]
    pub async fn ping(&self) -> AppResult<()> {
        self.db.ping().await.map_err(|e| {
            error!("数据库连接检查失败: {:?}", e);
            AppError::database_with_source("数据库连接不可用", e)
        })
    }

    /// 执行查询
    #[instrument(skip(self, select))]
    pub async fn execute_query<E>(
        &self,
        select: Select<E>,
    ) -> AppResult<Vec<E::Model>>
    where
        E: EntityTrait,
    {
        select
            .all(self.db.as_ref())
            .await
            .map_err(|e| {
                error!("查询执行失败: {:?}", e);
                AppError::database_with_source("查询执行失败", e)
            })
    }

    /// 开始事务
    #[instrument(skip(self))]
    pub async fn begin_transaction(&self) -> AppResult<DatabaseTransaction> {
        info!("开始数据库事务");
        self.db.begin().await.map_err(|e| {
            error!("开始事务失败: {:?}", e);
            AppError::database_with_source("事务开始失败", e)
        })
    }

    /// 提交事务
    #[instrument(skip(txn))]
    pub async fn commit_transaction(txn: DatabaseTransaction) -> AppResult<()> {
        info!("提交数据库事务");
        txn.commit().await.map_err(|e| {
            error!("提交事务失败: {:?}", e);
            AppError::database_with_source("事务提交失败", e)
        })
    }

    /// 回滚事务
    #[instrument(skip(txn))]
    pub async fn rollback_transaction(txn: DatabaseTransaction) -> AppResult<()> {
        info!("回滚数据库事务");
        txn.rollback().await.map_err(|e| {
            error!("回滚事务失败: {:?}", e);
            AppError::database_with_source("事务回滚失败", e)
        })
    }
}

/// 构建器模式的查询条件帮助类
pub struct QueryConditionBuilder<E: EntityTrait> {
    select: Select<E>,
}

impl<E: EntityTrait> QueryConditionBuilder<E> {
    pub fn new() -> Self {
        Self {
            select: E::find(),
        }
    }

    /// 添加可选的模糊查询条件
    pub fn add_like_condition<C>(mut self, column: C, value: Option<String>) -> Self
    where
        C: sea_orm::ColumnTrait,
    {
        if let Some(val) = value {
            if !val.trim().is_empty() {
                self.select = self.select.filter(column.like(format!("%{}%", val)));
            }
        }
        self
    }

    /// 添加可选的相等条件
    pub fn add_eq_condition<C, V>(mut self, column: C, value: Option<V>) -> Self
    where
        C: sea_orm::ColumnTrait,
        V: Into<sea_orm::Value>,
    {
        if let Some(val) = value {
            self.select = self.select.filter(column.eq(val));
        }
        self
    }

    /// 添加可选的IN条件
    pub fn add_in_condition<C, V>(mut self, column: C, values: Option<Vec<V>>) -> Self
    where
        C: sea_orm::ColumnTrait,
        V: Into<sea_orm::Value>,
    {
        if let Some(vals) = values {
            if !vals.is_empty() {
                self.select = self.select.filter(column.is_in(vals));
            }
        }
        self
    }

    /// 添加排序
    pub fn add_order_by<C>(mut self, column: C, order: sea_orm::Order) -> Self
    where
        C: sea_orm::ColumnTrait,
    {
        self.select = self.select.order_by(column, order);
        self
    }

    /// 添加限制条件
    pub fn add_limit(mut self, limit: Option<u64>) -> Self {
        if let Some(l) = limit {
            self.select = self.select.limit(l);
        }
        self
    }

    /// 添加偏移量
    pub fn add_offset(mut self, offset: Option<u64>) -> Self {
        if let Some(o) = offset {
            self.select = self.select.offset(o);
        }
        self
    }

    /// 构建查询
    pub fn build(self) -> Select<E> {
        self.select
    }
}

impl<E: EntityTrait> Default for QueryConditionBuilder<E> {
    fn default() -> Self {
        Self::new()
    }
} 